package com.all.widget;

import android.content.Context;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.animation.TranslateAnimation;
import android.widget.ScrollView;

/**
 * @ClassName: PullScrollView
 * @Description: 下拉背景返回控件
 * @author ankywtw@163.com
 * @date 2015-6-27 上午10:52:56
 * 
 */
public class PullScrollView extends ScrollView {

	/** 阻尼系数,越小阻力就越大. */
	private static final float SCROLL_RATIO = 0.5f;

	/** 头部view. */
	private View mHeader;

	/** ScrollView的content view. */
	private View mContentView;

	/** 头部图片初始顶部和底部. */
	private int mInitTop, mInitBottom;

	/** 首次点击的Y坐标. */
	private float mTouchDownY;

	/** 头部图片拖动时顶部和底部. */
	private int mCurrentTop, mCurrentBottom;
	
	  /** 是否开始移动. */
    private boolean isMoving = false;
    
    /** 是否移动到顶部位置. */
    private boolean isTop = false;
	
	 /** ScrollView的content view矩形. */
    private Rect mContentRect = new Rect();

	private enum State {
		/** 顶部 */
		UP,
		/** 底部 */
		DOWN,
		/** 正常 */
		NORMAL
	}

	/** 状态. */
	private State mState = State.NORMAL;

	/**
	 * @param context
	 */
	public PullScrollView(Context context) {
		super(context);
		init(context, null);
	}

	public PullScrollView(Context context, AttributeSet attrs) {
		super(context, attrs);
		init(context, attrs);
	}

	public PullScrollView(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
		init(context, attrs);
	}

	/**
     * 设置Header
     *
     * @param view
     */
    public void setHeader(View view) {
        mHeader = view;
    }

    
	/**
	 * @Description:
	 * @param :@param context
	 * @param :@param object
	 */
	private void init(Context context, Object object) {
		// TODO Auto-generated method stub
		setOverScrollMode(OVER_SCROLL_NEVER);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see android.view.View#onFinishInflate()
	 */
	@Override
	protected void onFinishInflate() {
		// TODO Auto-generated method stub
		if (getChildCount() > 0){
			mContentView = getChildAt(0);
		}

		super.onFinishInflate();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * android.widget.ScrollView#onInterceptTouchEvent(android.view.MotionEvent)
	 */
	@Override
	public boolean onInterceptTouchEvent(MotionEvent ev) {
		// TODO Auto-generated method stub
		if (ev.getAction() == MotionEvent.ACTION_DOWN) {
			mTouchDownY = ev.getY();
			if (mHeader != null) {
				mInitTop = mCurrentTop = mHeader.getTop();
				mInitBottom = mCurrentBottom = mHeader.getBottom();
			}
		}
		return super.onInterceptTouchEvent(ev);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see android.widget.ScrollView#onTouchEvent(android.view.MotionEvent)
	 */
	@Override
	public boolean onTouchEvent(MotionEvent ev) {
		// TODO Auto-generated method stub
		if (mContentView != null)
			doTouchEvent(ev);
		return super.onTouchEvent(ev);
	}

	/**
	 * @Description:
	 * @param :@param ev
	 */
	private void doTouchEvent(MotionEvent ev) {
		// TODO Auto-generated method stub
		int action = ev.getAction();
		switch (action) {
		case MotionEvent.ACTION_MOVE:
			 doActionMove(ev);
			break;

		case MotionEvent.ACTION_UP:
			 // 回滚动画
            if (isNeedAnimation()) {
                rollBackAnimation();
            }
			 isMoving = false;
             //mEnableTouch = false;
			break;

		default:
			break;
		}
	}

	/** 
	* @Description: 
	* @param :@param ev  
	*/
	private void doActionMove(MotionEvent ev) {
		// TODO Auto-generated method stub
		if(getScrollY()==0)
		{
			mState = State.NORMAL;
			if(isTop)
			{
				mTouchDownY = ev.getY();
				isTop = false;
			}
			
		}
		
		 if (mContentRect.isEmpty()) {
             // 保存正常的布局位置
             mContentRect.set(mContentView.getLeft(), mContentView.getTop(), mContentView.getRight(),
                     mContentView.getBottom());
         }
		 
		float deltaY = ev.getY() - mTouchDownY;
		
		if(mState == State.NORMAL&&deltaY>0)
		{
			mState = State.DOWN;
		}else if(mState == State.NORMAL&&deltaY<0)
		{
			mState = State.UP;
		}
		
		 if (mState == State.UP) {

	            isMoving = false;

	        } else if (mState == State.DOWN) {
	            if (getScrollY() <= deltaY) {
	                isMoving = true;
	            }
	        }
		 
		 if (isMoving) {

	            // 计算header移动距离(手势移动的距离*阻尼系数*0.5)
	            float headerMoveHeight = deltaY * 0.5f * SCROLL_RATIO;
	            mCurrentTop = (int) (mInitTop + headerMoveHeight);
	            mCurrentBottom = (int) (mInitBottom + headerMoveHeight);

	            // 计算content移动距离(手势移动的距离*阻尼系数)
	            float contentMoveHeight = deltaY * SCROLL_RATIO;

	            // 修正content移动的距离，避免超过header的底边缘
	            int top = (int) (mContentRect.top + contentMoveHeight);
	            int bottom = (int) (mContentRect.bottom + contentMoveHeight);

	            if (top <= mCurrentBottom) {
	                // 移动content view
	                mContentView.layout(mContentRect.left, top, mContentRect.right, bottom);

	                // 移动header view
	                mHeader.layout(mHeader.getLeft(), mCurrentTop, mHeader.getRight(), mCurrentBottom);
	            }
	        }
		
		
	}
	
	/* (non-Javadoc)
	 * @see android.view.View#onScrollChanged(int, int, int, int)
	 */
	@Override
	protected void onScrollChanged(int l, int t, int oldl, int oldt) {
		// TODO Auto-generated method stub
		if(getScrollY()==0)
			isTop=true;
		super.onScrollChanged(l, t, oldl, oldt);
	}

	  private void rollBackAnimation() {
		  TranslateAnimation tranAnim = new TranslateAnimation(0, 0,
	                Math.abs(mInitTop - mCurrentTop), 0);
		  tranAnim.setDuration(200);
		  mHeader.startAnimation(tranAnim);
		  mHeader.layout(mHeader.getLeft(), mInitTop, mHeader.getRight(), mInitBottom);
		  
		  
		  TranslateAnimation innerAnim = new TranslateAnimation(0, 0, mContentView.getTop(), mContentRect.top);
	        innerAnim.setDuration(200);
	        mContentView.startAnimation(innerAnim);
	        mContentView.layout(mContentRect.left, mContentRect.top, mContentRect.right, mContentRect.bottom);

	        mContentRect.setEmpty();
	  }
	/**
	 * 是否需要开启动画
	 */
	private boolean isNeedAnimation() {
		 return !mContentRect.isEmpty() && isMoving;
	}

}
